package com.geh.learn.hutool;

import cn.hutool.crypto.asymmetric.Sign;
import com.google.common.io.BaseEncoding;

import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class SignTest {

    public static final String publicKeyBase64 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCHo/d5q6E7cvU2+dF7lS2hWB7V3sBlnidBXv4zP3R4MIC/yy5YjXQnb71YC/+7r8JU3FLOSCxt4P6JOWpz1wLf/8rwDSFye3DFqPfEl5yRpoWas3amu8PAXVvWwyKuOAC4jC433cdqeR5fNEwkhstnPbyQ5/1xZajuIxQuFCyIYQIDAQAB";

    public static final String privateKeyBase64 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIej93mroTty9Tb50XuVLaFYHtXewGWeJ0Fe/jM/dHgwgL/LLliNdCdvvVgL/7uvwlTcUs5ILG3g/ok5anPXAt//yvANIXJ7cMWo98SXnJGmhZqzdqa7w8BdW9bDIq44ALiMLjfdx2p5Hl80TCSGy2c9vJDn/XFlqO4jFC4ULIhhAgMBAAECgYAA6dLuuv/zYdg6gBsH1FLF5m1SOr1UTdjlMvvemdm5nbd/OyG3M1Al/BXUAgQtRg8mocNtu80PShuirkwcBrWQbJbv0Y2TGamG1oFwzwMPt/g/TKC35Xf/8U5BMOX4PU/qOZse8V798MoD0J9c8YY5bUIR1ZGxL6ttkd5UGbObAQJBAPnVjvwn1dJwhSxLz4vHe+2g0mQa+gWa1CGAjpbFbM5ccX6RUFOWEatNGVvf7ME7qthQjaVPPxg15KQA5eOXD+ECQQCK/O/0gQKCbIwGUTVtXMznNjOEdk70gczXNKdT5fev0LSIWshK0dm14N/11NlkOheynKZ5hQseNvfG2QBQXoiBAkBtUOiTpMqGnf1neHSD8PFk9K2aZ8NmmGyhjCLYDeKiGQkAHI1NRajNj5q8/KoXkwgaRoT0BEzTRyGYMVxlzT+BAkBhRdL+cUf7VdLOHQniZ190tkdp/o8Vqr5dI5m0Ky+lWdDv2XFyg9n149N6rqQS9GFffSk5xTZZyCizf24r0W2BAkEA4FBbBbrOooRkMtryUHzHjOHaO8oxL7R/MYAO2FKK/Fo/NmZJXXohJBndxWqAQjsDjRZykvVg4mSaqV//lpr8DQ==";

    public static Sign sign = new Sign("SHA256withRSA", privateKeyBase64, publicKeyBase64);

    public static String sign(String original) throws Exception {

        // 准备需要签名的数据
        byte[] dataBytes = original.getBytes(StandardCharsets.UTF_8);

        // 使用私钥对数据进行签名
        Signature signature = Signature.getInstance("SHA256withRSA");
        PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(BaseEncoding.base64().decode(privateKeyBase64));
        RSAPrivateKey privateKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(priKeySpec);
        signature.initSign(privateKey);
        signature.update(dataBytes);
        byte[] signatureBytes = signature.sign();

        // 使用Guava的BaseEncoding工具类将签名转换为可读的字符串
        return BaseEncoding.base64().encode(signatureBytes);
    }

    public static boolean verify(String original, String sign) throws Exception {

        // 准备需要校验签名的数据
        byte[] dataBytes = original.getBytes(StandardCharsets.UTF_8);
        
        // 使用私钥对数据进行签名
        Signature signature = Signature.getInstance("SHA256withRSA");
        X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(BaseEncoding.base64().decode(publicKeyBase64));
        RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(pubKeySpec);
        signature.initVerify(publicKey);
        signature.update(dataBytes);
        
        return signature.verify(BaseEncoding.base64().decode(sign));
    }

    public static void main(String[] args) throws Exception {
        String original = "Hello World!";
        String signSelf = sign(original);
        String signHutool = BaseEncoding.base64().encode(sign.sign(original));
        System.out.println("signSelf " + signSelf);
        System.out.println("signHutool " + signHutool);
        System.out.println("signSelf vs  signHutool   " + signSelf.equals(signHutool));

        System.out.println("hutool verify " + sign.verify(original.getBytes(StandardCharsets.UTF_8), BaseEncoding.base64().decode(signSelf)));

        System.out.println("Self verify " + verify(original, signSelf));
    }

}
